/*
 * Copyright 2020-2030 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
*/

package com.gitee.minimalismstyle.fresh.flowable.api.feign

import org.springframework.web.bind.annotation.*
import com.gitee.minimalismstyle.fresh.common.core.domain.R
import com.gitee.minimalismstyle.fresh.flowable.api.annotation.FlowableClient
import com.gitee.minimalismstyle.fresh.flowable.api.config.FlowableFeignConfig
import com.gitee.minimalismstyle.fresh.flowable.api.feign.model.ProcessInstanceVariableCollectionResource
import com.gitee.minimalismstyle.fresh.flowable.api.feign.model.ProcessInstanceVariableResource
import com.gitee.minimalismstyle.fresh.flowable.api.feign.model.RestVariable
import org.springframework.http.MediaType
import org.springframework.web.multipart.MultipartFile

/**
 * ProcessInstanceVariables
 * @author maoxiaodong
 */
@FlowableClient(configuration = [FlowableFeignConfig::class])
interface ProcessInstanceVariablesApi {


    /**
     * In case the variable is a binary variable or serializable, the valueUrl points to an URL to fetch the raw value. If it’s a plain variable, the value is present in the response. Note that only local scoped variables are returned, as there is no global scope for process-instance variables.
     */
    @GetMapping("/runtime/process-instances/{processInstanceId}/variables")
    fun listProcessInstanceVariables(
        @PathVariable("processInstanceId") processInstanceId: String,
        @RequestParam(name = "scope", required = false) scope: String?
    ): R<Any>

    /**
     * This endpoint can be used in 2 ways: By passing a JSON Body (RestVariable or an array of RestVariable) or by passing a multipart/form-data Object.
    Nonexistent variables are created on the process-instance and existing ones are overridden without any error.
    Any number of variables can be passed into the request body array.
    Note that scope is ignored, only local variables can be set in a process instance.
    NB: Swagger V2 specification does not support this use case that is why this endpoint might be buggy/incomplete if used with other tools.
     */
    @PostMapping(value=["/runtime/process-instances/{processInstanceId}/variables"], consumes = [MediaType.MULTIPART_FORM_DATA_VALUE])
    fun createProcessInstanceVariable(
        @PathVariable("processInstanceId") processInstanceId: String,
        @RequestBody(required = false) body: ProcessInstanceVariableCollectionResource?,
        @RequestParam(name = "file", required = false) file: MultipartFile?,
        @RequestParam(name = "name", required = false) name: String?,
        @RequestParam(name = "type", required = false) type: String?
    ): R<Any>

    /**
     * This endpoint can be used in 2 ways: By passing a JSON Body (RestVariable or an array of RestVariable) or by passing a multipart/form-data Object.
    Nonexistent variables are created on the process-instance and existing ones are overridden without any error.
    Any number of variables can be passed into the request body array.
    Note that scope is ignored, only local variables can be set in a process instance.
    NB: Swagger V2 specification does not support this use case that is why this endpoint might be buggy/incomplete if used with other tools.
     */
    @PutMapping(value=["/runtime/process-instances/{processInstanceId}/variables"], consumes = [MediaType.MULTIPART_FORM_DATA_VALUE])
    fun createOrUpdateProcessVariable(
        @PathVariable("processInstanceId") processInstanceId: String,
        @RequestBody(required = false) body: ProcessInstanceVariableCollectionResource?,
        @RequestParam(name = "file", required = false) file: MultipartFile?,
        @RequestParam(name = "name", required = false) name: String?,
        @RequestParam(name = "type", required = false) type: String?
    ): R<Any>

    /**
     * Delete all variables
     */
    @DeleteMapping("/runtime/process-instances/{processInstanceId}/variables")
    fun deleteLocalProcessVariable(
        @PathVariable("processInstanceId") processInstanceId: String
    ): R<Any>

    /**
     * Get a variable for a process instance
     */
    @GetMapping("/runtime/process-instances/{processInstanceId}/variables/{variableName}")
    fun getProcessInstanceVariable(
        @PathVariable("processInstanceId") processInstanceId: String,
        @PathVariable("variableName") variableName: String,
        @RequestParam(name = "scope", required = false) scope: String?
    ): R<RestVariable>

    /**
     * This endpoint can be used in 2 ways: By passing a JSON Body (RestVariable) or by passing a multipart/form-data Object.
    Nonexistent variables are created on the process-instance and existing ones are overridden without any error.
    Note that scope is ignored, only local variables can be set in a process instance.
    NB: Swagger V2 specification does not support this use case that is why this endpoint might be buggy/incomplete if used with other tools.
     */
    @PutMapping(value=["/runtime/process-instances/{processInstanceId}/variables/{variableName}"], consumes = [MediaType.MULTIPART_FORM_DATA_VALUE])
    fun updateProcessInstanceVariable(
        @PathVariable("processInstanceId") processInstanceId: String,
        @PathVariable("variableName") variableName: String,
        @RequestBody(required = false) body: ProcessInstanceVariableResource?,
        @RequestParam(name = "file", required = false) file: MultipartFile?,
        @RequestParam(name = "name", required = false) name: String?,
        @RequestParam(name = "type", required = false) type: String?
    ): R<RestVariable>

    /**
     * Delete a variable
     */
    @DeleteMapping("/runtime/process-instances/{processInstanceId}/variables/{variableName}")
    fun deleteProcessInstanceVariable(
        @PathVariable("processInstanceId") processInstanceId: String,
        @PathVariable("variableName") variableName: String,
        @RequestParam(name = "scope", required = false) scope: String?
    ): R<Any>

    /**
     * Get the binary data for a variable
     */
    @GetMapping("/runtime/process-instances/{processInstanceId}/variables/{variableName}/data")
    fun getProcessInstanceVariableData(
        @PathVariable("processInstanceId") processInstanceId: String,
        @PathVariable("variableName") variableName: String,
        @RequestParam(name = "scope", required = false) scope: String?
    ): R<Any>
}